import java.util.Date;

/***********************************************************************************
 * ELEC5616 Computer and Network Security, The University of Sydney Copyright
 * (C) 2002-2004, Matt Barrie, Stephen Gould and Ryan Junee
 * 
 * PROJECT: StealthNet FILENAME: StealthNetPacket.java AUTHORS: Matt Barrie,
 * Stephen Gould and Ryan Junee DESCRIPTION: Implementation of StealthNet
 * Communications for ELEC5616 programming assignment. This code has been
 * written for the purposes of teaching cryptography and computer security. It
 * is to be used as a demonstration only. No attempt has been made to optimise
 * the source code. VERSION: 1.0-ICE
 * 
 * REVISION HISTORY:
 * 
 **********************************************************************************/

public class StealthNetPacket {
	public static final byte CMD_NULL = 0x00;
	public static final byte CMD_LOGIN = 0x01;
	public static final byte CMD_LOGOUT = 0x02;
	public static final byte CMD_MSG = 0x03;
	public static final byte CMD_CHAT = 0x04;
	public static final byte CMD_FTP = 0x05;
	public static final byte CMD_LIST = 0x06;
	public static final byte CMD_CREATESECRET = 0x07;
	public static final byte CMD_SECRETLIST = 0x08;
	public static final byte CMD_GETSECRET = 0x09;
	public static final byte CMD_GETMONEY = 0x0A;
	public static final byte CMD_VERIFYPAYMENT = 0x0B;
	public static final byte CMD_RECVMONEY = 0x0C;
	public static final byte CMD_PAY = 0x0D;
	public static final byte CMD_RECVSIG = 0x0E;
	public static final byte CMD_DH_KEY = 0x10;

	private static final char[] HEXTABLE = { '0', '1', '2', '3', '4', '5', '6',
			'7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

	private static final String DELIMITER = ":"; // delimiter to separate data,
													// timestamp and mac

	byte command; // command
	byte data[]; // data
	byte mac[]; // mac
	Date timestamp; // timestamp

	public StealthNetPacket() {
		command = CMD_NULL;
		data = new byte[0];
		mac = new byte[0];
		timestamp = new Date();
	}

	public StealthNetPacket(byte cmd, byte[] d) {
		command = cmd;
		timestamp = new Date();
		if (d == null) {
			data = new byte[0];
			mac = new byte[0];
		} else
			data = d;
	}

	public StealthNetPacket(String str) {
		// if (str.length() % 2 == 1)
		// str = "0" + str;

		if (str.length() == 0) {
			command = CMD_NULL;
			data = new byte[0];
			mac = new byte[0];
		} else {
			command = (byte) (16 * hexToInt(str.charAt(0)) + hexToInt(str
					.charAt(1)));
			String[] combo = str.substring(2).split(DELIMITER);
			data = hexStringToByte(combo[0]);
			timestamp = new Date(Long.parseLong(new String(
					hexStringToByte(combo[1]))));
			if (combo.length > 2)
				mac = hexStringToByte(combo[2]);
			else
				mac = new byte[0];
		}
	}

	public String toString() {
		byte[] cmd = new byte[1];
		cmd[0] = command;

		String str = byteToHexString(cmd)
				+ byteToHexString(data)
				+ DELIMITER
				+ byteToHexString(String.valueOf(timestamp.getTime())
						.getBytes());

		if (mac != null && mac.length > 0)
			str += DELIMITER + byteToHexString(mac);

		return str;
	}

	private String byteToHexString(byte[] data) {
		int i, lowByte, highByte;
		String str = "";

		for (i = 0; i < data.length; i++) {
			highByte = (data[i] >= 0) ? data[i] : 256 + data[i];
			lowByte = highByte & 15;
			highByte /= 16;
			str += HEXTABLE[highByte];
			str += HEXTABLE[lowByte];
		}
		return str;
	}

	private byte[] hexStringToByte(String hex) {
		byte[] data = new byte[hex.length() / 2];
		for (int i = 0; i < data.length; i++)
			data[i] = (byte) (16 * hexToInt(hex.charAt(2 * i)) + hexToInt(hex
					.charAt(2 * i + 1)));
		return data;
	}

	private static int hexToInt(char hex) {
		if ((hex >= '0') && (hex <= '9'))
			return (hex - '0');
		if ((hex >= 'A') && (hex <= 'F'))
			return (hex - 'A' + 10);
		if ((hex >= 'a') && (hex <= 'f'))
			return (hex - 'a' + 10);
		return 0;
	}
}

/******************************************************************************
 * END OF FILE: StealthNetPacket.java
 *****************************************************************************/
